-module(megatest).

-export([test/1]).

log(Reply) ->
    case Reply of
	{ok,_,_} -> 
	    io:format("reply = ~w~n", [Reply])
    end.
    
test([Mod,Func,Args]) ->
    Nums = list_to_integer(atom_to_list(Args)),
    %io:format("Func=~w, Args=~w, Nums=~w~n", [Func,Args,Nums]),
    
    Results = try testSuite(Mod,Func,Nums,[]) of
		 Val -> Val
	     catch 
		 _: Reason ->
		     io:format("test catch excepiton = ~p~n", [{Reason,  erlang:get_stacktrace()}]),
		     [{error,testsuiteexception}]
	     end,
    
    io:format("Test Result have ~w , content=~w~n", [lists:flatlength(Results), Results]),
    %quit
    init:stop().

testSuite_0(Mod,Fun,Nums,Result) ->
    case Nums of
	0 -> Result;
	_ -> 
	    L = [Mod:Fun()|Result],
	    testSuite(Mod,Fun, Nums-1, L)
    end.

testSuite(Mod,Fun,Nums,Results) ->
    PPid = self(),
    producer(Nums,PPid,Mod,Fun),
    boss(Nums,Results).
	
producer(0,_PPid,_Mod,_Fun) ->
    ok;
producer(Nums,PPid,Mod,Fun) ->
    Pid = spawn( fun() -> worker(Mod,Fun,PPid) end ),
    io:format("create ~w~n", [Pid]),
    producer(Nums-1,PPid,Mod,Fun).

boss(0,Results) ->
    Results;
boss(Nums,Results) ->
    receive
	{result,Pid,Result} ->
	    io:format("recv ~w response~n", [Pid]),
	    boss(Nums-1,[Result|Results]);
	_Other ->
	    boss(Nums-1,[{unknownresp}|Results])
    after 500000 ->
	    [{error,workertimeout}|Results]
    end.

worker(Mod,Fun,PPid) ->
    try Mod:Fun() of
	Val -> 
	    PPid ! {result,self(),Val}
    catch
	_: Reason ->	
	    io:format("worker catch excepiton = ~p~n", [{Reason,  erlang:get_stacktrace()}]),
	    PPid ! {result,self(),{error,workerexception}}
    end.

